<?php

/**
 * Mid-advanced file lister.
 *
 * @package				fLister
 * @version				3.0-ALPHA1
 * @author				Sebastian Dudek <contact@dedikownia.org>
 * @link					http://code.google.com/p/flister/
 * @license				http://opensource.org/licenses/gpl-license.php GNU General Public License v3
 */


/*
 * 
 */
class fLister {
  /*
   *  Tablica zawierająca konfiguracje skryptu
   * 
   * @static
   * @access public
   * @var array
   */
  public static
    $config = array();
  
  /*
   * Akcja która ma zostać wywołana
   * 
   * @access private
   * @var string
   */
  private
    $action = 'lister';
  
  /*
   * Tablica trzymajaca metody _GET
   * 
   * @access private
   * @var array
   */
  private
    $_get = array();
  
  /*
   * Tablica trzymajaca metody _POST
   * 
   * @access private
   * @var array
   */
  private
    $_post = array();
  
  /*
   * Konstruktor klasy.
   * 
   * @access public
   * @param array $config tablica z konfiguracja
   */
  public function __construct(array $config) {
    self::$config  = $config;
    $this->_get    = $_GET;
    $this->_post   = $_POST;
    
    spl_autoload_register(__CLASS__ . "::__autoload");
    
    if(isset($this->_get['action'])) {
      $this->action = $this->_get['action'];
    }
    
    if(!file_exists(self::$config['rootDir'])) {
      throw new Exception("Error: Root dir don't exists!");
    }
  }
  
  /*
   * Metoda ładująca pliki z klasą.
   * 
   * @access public
   * @param string $className nazwa klasy której plik ma zostać załadowany
   */
  public static function __autoload($className) {
    include __DIR__ . "/$className.php";
  }
  
  /*
   * Metoda uruchamiająca akcje która ma zostać wykonana.
   * 
   * @access private
   */
  public function run() {
    $accessibleActions = get_class_methods($this);
    $accessibleActions = array_map("strtolower", $accessibleActions);
    
    $runAction = "action{$this->action}";

    if(!in_array($runAction, $accessibleActions)) {
      throw new Exception("Error: Action don't exists!");
    }
	    
    $this->$runAction();
    
    $this->display();
  }
  
  /*
   * 
   */
  private function generateBreadcrumbs($dir = null) {
    
  }
  
  /*
   * 
   */
  private function display() {
    $this->generateBreadcrumbs();
    //$this->view->generate()->display();
  }
  
  /*
   * 
   */
  private function setCoreHeaders($mime, $name, $size) {
    header('Content-Type: '.$mime);
    header('Content-Disposition: attachment; filename="'.$name.'"');
    header('Content-Transfer-Encoding: binary');
    header('Content-Length: '. $size);
    header('Expires: 0');
    header('Pragma: no-cache');
  }
  
  /*
   * Metoda akcji od listowania plików.
   * 
   * $access private
   */
  private function actionLister() {
    $dir = self::$config['rootDir'] . (isset($this->_get['dir']) ? $this->_get['dir'] : null);
    $files = array();
    $dirs = array();
       
    foreach(new SortableDirectoryIterator($dir) as $data) {
      $filePath = str_replace(self::$config['rootDir'], "", $data->getPathname());
      
      if($data->isDot()) {
        continue;
      }
      
      if($data->isDir()) {
        $dirs[] = array(
            'name'  => $data->getFilename(),
            'path'  => $filePath,
            'size'  => $data->getBSize(),
            'mtime' => $data->getFormatMTime(),
          );
      }
      
      if($data->isFile()) {
        $files[] = array(
            'name'  => $data->getFilename(),
            'path'  => $filePath,
            'size'  => $data->getBSize(),
            'mtime' => $data->getFormatMTime(),
            'type'  => null,
          );        
      }
    }    
  }
  
  /*
   * 
   */
  private function actionDownload() {
    $filePath = self::$config['rootDir'] . $this->_get['file'];
    if(file_exists($filePath) && is_file($filePath) && is_readable($filePath)) {
      $fileInfo = new SplFileInfo($filePath);
      // @TODO Przenieś mimeType
      $finfo = new finfo(FILEINFO_MIME_TYPE);
      $mime = $finfo->file($fileInfo->getPathname());
      
      $this->setCoreHeaders($mime, $fileInfo->getBasename(), $fileInfo->getSize());

      flush();
      
      if(self::$config['downloadRate'] !== false) {
        $f = fopen($fileInfo->getPathname(), "r");
        
        while(!feof($f)) {
          print fread($f, round(self::$config['downloadRate'] * 1024));
          flush();
          sleep(1);
        }        
      } else {
        $f = fopen($fileInfo->getPathname(), 'rb');
        fpassthru($f);
      }
      fclose($f);
    }
  }
  
  /*
   * 
   */
  private function actionCreateArchive() {
  }
}

?>